﻿#ifndef CPAYPLATPROXY_H
#define CPAYPLATPROXY_H

#include "IPayplatInterface.h"

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QString>

#include <mutex>
#include <map>

struct MapRequest {
    zl::PayRequest request;
    int32_t ttl;

    MapRequest(const zl::PayRequest req, int32_t timeout = 20)
        : request(req)
        , ttl(timeout) {}
};

class CPayplatProxy : public QObject, public zl::IPayplatInterface
{
    Q_OBJECT

public:
    static CPayplatProxy* Instance();
    static void Release();

    int32_t Initialize(const zl::PayplatConfig& config, zl::IPayplatObserver* obs = nullptr) override;
    void Uninitialize() override;
    int32_t EnableOneCode(bool flag) override;
    int32_t FindOrder(const zl::PayRequest& req) override;
    int32_t CreateOrder(const zl::PayRequest& req) override;
    int32_t CheckOrder(const zl::PayRequest& req) override;
    int32_t GetQRCode(const std::string &url, char **buf, int32_t &size) override;

protected:
    std::string create_request_body(const zl::PayRequest& req);
    std::string create_request_content(const zl::PayRequest& req);
    std::string get_reply_body(QByteArray body);
    zl::EPayError convert_http_status_code(int code);
    zl::EPayError process_reply_body(const std::string body, zl::PayReply& rep);

    void timerEvent(QTimerEvent* e);

signals:
    void sendRequest(const zl::PayRequest request);

protected slots:
    void send_request(const zl::PayRequest request);
    void on_network_request_finished(QNetworkReply* rep);

private:
    CPayplatProxy();
    ~CPayplatProxy();

    static CPayplatProxy*                   instance_;
    QNetworkAccessManager*                  mgr_;
    zl::PayplatConfig                       config_;
    zl::IPayplatObserver*                   obs_;
    std::map<std::string, MapRequest>       request_map_;
    std::mutex                              request_map_mutex_;
    int                                     request_timer_;
    bool                                    enable_onecode_;
};

#endif // CPAYPLATPROXY_H
